import threading
import time

import serial
import serial.tools.list_ports

#串口列表 (串口com口 串口句柄)
import Log

SERIAL_LIST  = []

SYS_STATUS = True

#关闭列表串口 并移除
def closeListSerial(port):
    global SERIAL_LIST
    for item in SERIAL_LIST:
        if item.port == port:
            item.close()
            SERIAL_LIST.remove(item)

#添加进列表
def openListSerial(port,bps):
    global SERIAL_LIST
    closeListSerial(port)
    ser = ThreadSerial(port,bps)
    if ser:
        ser.start_thread()
        if ser.is_status():
            SERIAL_LIST.append(ser)


def getListSerial(port):
    global SERIAL_LIST
    for item in SERIAL_LIST:
        if item.port == port:
            return item
    return None
def oneSendCmd(port,bps,text):
    ser = getListSerial(port)
    if ser == None:
        openListSerial(port=port,bps=bps)
        time.sleep(1)
    ser.write(text)
    time.sleep(0.5)
    str = syncRead(port)
    return str

def syncRead(port):
    ser=getListSerial(port)
    str = ''
    for item in ser.textList:
        str=str+item+'\n'

    if str:
        ser.textList.clear()
    return str



class ThreadSerial:

    def __init__(self, port , bps):
        self.ser = None
        self.textList = []
        self.serialThread = None
        self.get_str = ''
        self.port = port
        self.bps = bps

    def serial_thread(self):
        global SYS_STATUS
        while self.ser.is_open:
            if SYS_STATUS == False:
                break
            self.get_str = readData(self.ser)
            if self.get_str:
                self.textList.append(self.get_str)

    def start_thread(self):
        self.textList = []
        self.ser = openSerial(port=self.port,bps=self.bps)
        time.sleep(0.2)
        if self.ser:
            self.serialThread = threading.Thread(target=self.serial_thread)
            self.serialThread.start()
    def is_status(self):
        if self.ser == None:
            return False
        return self.ser.is_open

    def write(self,text,coding='gbk'):
        sendData(self.ser, text, coding)
    def close(self):
        return closeSerial(self.ser)


def searchSerial():
    port_list = list(serial.tools.list_ports.comports())
    if len(port_list) > 0:
        return port_list
    else:
        return None

def openSerial(port="COM1", bps=9600, timex=5):
    try:
        # 打开串口
        ser = serial.Serial(port, bps, timeout=timex)
        if ser.is_open:
            Log.serialLog("--- 串口打开 ---port:"+port+',bps:'+str(bps))
            return ser
    except Exception as e:
        Log.serialLog("--- 打开异常 ---: "+ str(e))
        return None
def sendData(ser, text, code="utf-8"):
    try:
        result = ser.write(text.encode(code))
        if result == len(text):
            Log.serialLog("--- 发送成功 ---："+text)
            Log.serialLog("--- 发送返回 ---：" + str(result))
            return result
        else:
            Log.serialLog("--- 发送错误 ---：data len:"+str(len(text))+"send len:"+result)
            return None
    except Exception as e:
        Log.serialLog("--- 发送异常 ---："+str(e))
def readData(ser, code="utf-8"):
    if ser.inWaiting():
        print('开始读取')
        s_byte = ser.read(ser.inWaiting())
        try:
            s_byte_str = s_byte.decode(code)
            print(s_byte_str)
        except Exception:
            s_byte_str = r'\x' + s_byte.hex().replace('x', r'\x')
            Log.serialLog("--- 数据为byte格式需要转换 ---")
        Log.serialLog("--- 读到数据 ---："+s_byte_str)
        return s_byte_str
    else:
        return None
def closeSerial(ser):
    if ser.is_open:
        try:
            ser.close()
            Log.serialLog("--- 串口关闭 ---")
            return 0
        except Exception as e:
            Log.serialLog("--- 关闭异常 ---："+str(e))
            return -1
    else:
        Log.serialLog("--- 错误 ---：串口未打开！")
        return -1